import json
import os
import time

from .leetcode_operation import LeetCodeOperation


class QuestionTopicsList(LeetCodeOperation):
    def __init__(self, requests_manager, base_url="https://leetcode.cn", **params):
        super().__init__(requests_manager, base_url)
        self.params = params.get('params')
        self.filename="question_topics_list.json"
        self.endpoint = 'graphql'

    def generate_payload(self):
        query_string = "\n    query questionTopicsList($questionSlug: String!, $skip: Int, $first: Int, $orderBy: SolutionArticleOrderBy, $userInput: String, $tagSlugs: [String!]) {\n  questionSolutionArticles(\n    questionSlug: $questionSlug\n    skip: $skip\n    first: $first\n    orderBy: $orderBy\n    userInput: $userInput\n    tagSlugs: $tagSlugs\n  ) {\n    totalNum\n    edges {\n      node {\n        ipRegion\n        rewardEnabled\n        canEditReward\n        uuid\n        title\n        slug\n        sunk\n        chargeType\n        status\n        identifier\n        canEdit\n        canSee\n        reactionType\n        hasVideo\n        favoriteCount\n        upvoteCount\n        reactionsV2 {\n          count\n          reactionType\n        }\n        tags {\n          name\n          nameTranslated\n          slug\n          tagType\n        }\n        createdAt\n        thumbnail\n        author {\n          username\n          profile {\n            userAvatar\n            userSlug\n            realName\n            reputation\n          }\n        }\n        summary\n        topic {\n          id\n          commentCount\n          viewCount\n          pinned\n        }\n        byLeetcode\n        isMyFavorite\n        isMostPopular\n        isEditorsPick\n        hitCount\n        videosInfo {\n          videoId\n          coverUrl\n          duration\n        }\n      }\n    }\n  }\n}\n    "
        
        return {
            "query": query_string,
            "variables": self.params,
            "operationName": "questionTopicsList"
        }

    def parse_graphql_data(self, data):
        topics_data = data.get('data', {}).get('questionSolutionArticles', {})
        parsed_topics = {
            'totalNum': topics_data.get('totalNum'),
            'topics': []
        }

        for edge in topics_data.get('edges', []):
            node = edge.get('node', {})
            topic = {
                'ipRegion': node.get('ipRegion'),
                'rewardEnabled': node.get('rewardEnabled'),
                'uuid': node.get('uuid'),
                'title': node.get('title'),
                'slug': node.get('slug'),
                'sunk': node.get('sunk'),
                'chargeType': node.get('chargeType'),
                'status': node.get('status'),
                'identifier': node.get('identifier'),
                'canEdit': node.get('canEdit'),
                'canSee': node.get('canSee'),
                'reactionType': node.get('reactionType'),
                'hasVideo': node.get('hasVideo'),
                'favoriteCount': node.get('favoriteCount'),
                'upvoteCount': node.get('upvoteCount'),
                'createdAt': node.get('createdAt'),
                'thumbnail': node.get('thumbnail'),
                'author': {
                    'username': node.get('author', {}).get('username'),
                    'userAvatar': node.get('author', {}).get('profile', {}).get('userAvatar'),
                },
                'tags': [
                    {
                        'name': tag.get('name'),
                        'nameTranslated': tag.get('nameTranslated'),
                        'slug': tag.get('slug'),
                        'tagType': tag.get('tagType'),
                    } for tag in node.get('tags', [])
                ],
                # 如果还有其他字段，继续在这里添加
            }
            parsed_topics['topics'].append(topic)

        return parsed_topics



    def fetch_all_data(self, request_interval=1):
        all_data = []
        skip = 0
        first = 15  # constant variable
        totalNum = None

        while totalNum is None or skip < totalNum:
            self.params.update({'skip': skip})
            data = self.fetch_data(self.endpoint, method='POST')
            parsed_data = self.parse_graphql_data(data)
            topics = parsed_data.get('topics', [])
            all_data.extend(topics)

            totalNum = parsed_data.get('totalNum', 0)
            skip += first

            if skip >= totalNum:
                break

            time.sleep(request_interval)

        # self.save_json(all_data, self.filename)
        return all_data


    # Execute Method
    def execute(self):
        data = self.fetch_data(self.endpoint, method='POST')
        data = self.parse_graphql_data(data)
        self.save_json(data, self.filename)

    def execute_for_multiple_slugs(self, folder_path="QuestionTopicsList", request_interval=1):
        source_name = "ProblemsetQuestionList"
        slugs = self.read_all_title_slugs()
        os.makedirs(os.path.join(self.directory, folder_path), exist_ok=True)

        for slug in slugs:
            self.params.update({'questionSlug': slug})
            file_name = f"{slug}.json"
            file_path = os.path.join(folder_path, file_name)
            
            if os.path.exists(os.path.join(self.directory, folder_path, file_name)):
                continue
            
            self.logger.info(f"slug: {slug}")
            data = self.fetch_data(self.endpoint, method='POST')
            data = self.parse_graphql_data(data)
            if data and data.get("totalNum", 0) != 0:
                self.save_json(data, file_path)
            
            time.sleep(request_interval)